import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.PriorityQueue;

import org.junit.Test;


public class testAStarHeuristic {

	private static int DEPTH_PER_ITERATION = 3;
	
	private static class BoardPath implements Comparable<BoardPath>
	{
		Board board;
		String path;
		int depth;
		
		public BoardPath( Board board, String path, int depth )
		{
			this.board = board;
			this.path = path;
			
			this.depth = depth;
		}
		
		private int getDepthLevel()
		{
			return depth/DEPTH_PER_ITERATION;
		}
		
		private int manhattanDistance( Cord c1, Cord c2 )
		{
			return (Math.abs( c1.getX()-c2.getX() ) + Math.abs( c1.getY()-c2.getY() ));
		}
		
		private int minimumManhattanDistanceNotGoal( Board board, Cord start, Cord[] goals )
		{
			int min = Integer.MAX_VALUE;
			
			for( Cord goal : goals )
			{ 
				if ( board.getCellType( start ) != Board.CellType.BoxOnGoal )
				{
					min = Math.min( min , manhattanDistance(start, goal) );
				}
				
			}
			
			return min;
		}

		@Override
		public int compareTo(BoardPath arg0) 
		{
			int refDepth = arg0.getDepthLevel();
			int selfDepth = this.getDepthLevel();
			
			
			
			if ( selfDepth > refDepth )
			{
//				System.out.println("selfDepth:refDepth = "+ selfDepth +">"+refDepth );
				return 1;
			}
			else if ( selfDepth < refDepth )
			{
//				System.out.println("selfDepth:refDepth = "+ selfDepth +"<"+refDepth );
				return -1;
			}
			else
			{
				
				int ref = arg0.aStarHeuristic();
				int self = this.aStarHeuristic();
				
				if ( self < ref )
				{
					return -1;
				}
				else if ( self > ref )
				{
					return 1;
				}
				else
				{
//					return 0;
					return Integer.parseInt(path);
				}
				
			}
		}
		
	
		public int aStarHeuristic()
		{	
			return Integer.parseInt(path);
		}
	}
	
	@Test
	public void test() 
	{
//		BoardPath[] array = new BoardPath[]{ 
//				new BoardPath( null, "53", 1 ),
//				new BoardPath( null, "2", 2 ),
//				new BoardPath( null, "44", 3 ),
//				new BoardPath( null, "6", 4 ),
//				new BoardPath( null, "34",2 ),
//				new BoardPath( null, "25", 6 ),
//				new BoardPath( null, "2", 9 ),
//				new BoardPath( null, "99", 7 ),
//				new BoardPath( null, "1", 8 ),
//				};
		
		BoardPath[] array = new BoardPath[]{ 
				new BoardPath( null, "1", 1 ),
				new BoardPath( null, "2", 2 ),
				new BoardPath( null, "3", 3 ),
				new BoardPath( null, "4", 5 ),
				new BoardPath( null, "5",2 ),
				new BoardPath( null, "6", 6 ),
				new BoardPath( null, "1", 9 ),
				new BoardPath( null, "2", 7 ),
				new BoardPath( null, "4", 8 ),
				};
		
		PriorityQueue<BoardPath> queue = new PriorityQueue<BoardPath>();
		
		for ( BoardPath bp : array  )
		{
			queue.add(bp);
		}
		
//		Arrays.sort(array);	
		
		System.out.println( );
		System.out.println( "Unsorted array:" );
		
		for ( BoardPath bp : array )
		{
			System.out.println(bp.getDepthLevel() + " : "+ bp.path );
		}
		
		System.out.println( );
		System.out.println( "Queue:" );
//		for ( BoardPath bp : array  )
//		{
//			System.out.println( queue.remove().getDepthLevel() );
//		}
		
//		System.out.println();
		
		while( !queue.isEmpty() )
		{
			BoardPath bp = queue.remove();
			System.out.println(bp.getDepthLevel() + " : "+ bp.path );
		}
//		for ( BoardPath bp : queue )
//		{
//			
//		}
	}

}
